package cn.iocoder.yudao.module.base.service.productwarehouse;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.wms.api.warehouse.StockApi;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import cn.iocoder.yudao.module.base.controller.admin.productwarehouse.vo.*;
import cn.iocoder.yudao.module.base.dal.dataobject.productwarehouse.ProductWarehouseDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.base.dal.mysql.productwarehouse.ProductWarehouseMapper;

import javax.annotation.Resource;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.base.enums.ErrorCodeConstants.*;

/**
 * 产品仓储信息 Service 实现类
 *
 * @author LJX
 */
@Service
@Validated
public class ProductWarehouseServiceImpl implements ProductWarehouseService {

    @Resource
    private ProductWarehouseMapper productWarehouseMapper;
    @Resource
    private StockApi stockApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createProductWarehouse(ProductWarehouseSaveReqVO createReqVO) {
        validateProductExists(null, createReqVO.getProductId());
        // 插入
        ProductWarehouseDO productWarehouse = BeanUtils.toBean(createReqVO, ProductWarehouseDO.class);
        productWarehouseMapper.insert(productWarehouse);
        stockApi.initStock(createReqVO.getProductId());
        // 返回
        return productWarehouse.getId();
    }

    @Override
    public void updateProductWarehouse(ProductWarehouseSaveReqVO updateReqVO) {
        // 校验存在
        validateProductWarehouseExists(updateReqVO.getId());
        // 更新，且更新时不允许更新产品信息
        ProductWarehouseDO updateObj = BeanUtils.toBean(updateReqVO, ProductWarehouseDO.class);
        updateReqVO.setProductId(null);
        productWarehouseMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProductWarehouse(Long id) {
        // 校验存在
        ProductWarehouseDO productWarehouse = validateProductWarehouseExists(id);
        // TODO 已被使用不允许删除（查询各入库单据单身）
        // 删除库存汇总信息
        stockApi.deleteStockByProduct(productWarehouse.getProductId());
        // 删除
        productWarehouseMapper.deleteById(id);
    }

    private void validateProductExists(Long id, Long productId) {
        ProductWarehouseDO productWarehouse = productWarehouseMapper.selectByProductId(productId);
        if (ObjectUtil.isEmpty(productWarehouse)) {
            return;
        }
        if (ObjectUtil.isEmpty(id)) {
            throw exception(PRODUCT_WAREHOUSE_EXISTS);
        }
        if (!id.equals(productWarehouse.getId())) {
            throw exception(PRODUCT_WAREHOUSE_EXISTS);
        }
    }

    private ProductWarehouseDO validateProductWarehouseExists(Long id) {
        ProductWarehouseDO productWarehouse = productWarehouseMapper.selectById(id);
        if (ObjectUtil.isEmpty(productWarehouse)) {
            throw exception(PRODUCT_WAREHOUSE_NOT_EXISTS);
        }
        return productWarehouse;
    }

    @Override
    public ProductWarehouseDO getProductWarehouse(Long id) {
        return productWarehouseMapper.selectById(id);
    }

    @Override
    public ProductWarehouseDO getProductWarehouseByProduct(Long id) {
        return productWarehouseMapper.selectByProductId(id);
    }

    @Override
    public PageResult<ProductWarehouseDO> getProductWarehousePage(ProductWarehousePageReqVO pageReqVO) {
        return productWarehouseMapper.selectPage(pageReqVO);
    }

    @Override
    public ProductWarehouseDO getFirstProductWarehouseByInWarehouse(Long id) {
        return productWarehouseMapper.selectByInWarehouse(id);
    }

    @Override
    public ProductWarehouseDO getFirstProductWarehouseByOutWarehouse(Long id) {
        return productWarehouseMapper.selectByOutWarehouse(id);
    }

    @Override
    public ProductWarehouseDO getFirstProductWarehouseByInPosition(Long id) {
        return productWarehouseMapper.selectByInPosition(id);
    }

    @Override
    public ProductWarehouseDO getFirstProductWarehouseByOutPosition(Long id) {
        return productWarehouseMapper.selectByOutPosition(id);
    }

}